package jenkins

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/http/cookiejar"
	"strings"
	"time"

	"project-info/src/handle/common"
	"project-info/src/handle/response"
	"project-info/src/model"

	"github.com/bndr/gojenkins"
	"gorm.io/gorm"

	"project-info/src/lib"
)

// CredentialListReq 凭据列表请求
type CredentialListReq struct {
	common.PageRequest
	Keyword string `json:"keyword" form:"keyword"` // 搜索关键词
	Type    string `json:"type" form:"type"`       // 凭据类型筛选
}

// CredentialCreateReq 创建凭据请求
type CredentialCreateReq struct {
	CredentialId string `json:"credentialId" binding:"required"` // 凭据ID
	Description  string `json:"description"`                     // 描述
	Type         string `json:"type" binding:"required"`         // 凭据类型
	Username     string `json:"username"`                        // 用户名
	Password     string `json:"password"`                        // 密码
	PrivateKey   string `json:"privateKey"`                      // 私钥
	Passphrase   string `json:"passphrase"`                      // 密码短语
	SecretText   string `json:"secretText"`                      // 密钥文本
	Certificate  string `json:"certificate"`                     // 证书
	Scope        string `json:"scope"`                           // 作用域
}

// CredentialUpdateReq 更新凭据请求
type CredentialUpdateReq struct {
	Id           uint64 `json:"id" binding:"required"`           // 凭据数据库ID
	CredentialId string `json:"credentialId" binding:"required"` // 凭据ID
	Description  string `json:"description"`                     // 描述
	Type         string `json:"type" binding:"required"`         // 凭据类型
	Username     string `json:"username"`                        // 用户名
	Password     string `json:"password"`                        // 密码
	PrivateKey   string `json:"privateKey"`                      // 私钥
	Passphrase   string `json:"passphrase"`                      // 密码短语
	SecretText   string `json:"secretText"`                      // 密钥文本
	Certificate  string `json:"certificate"`                     // 证书
	Scope        string `json:"scope"`                           // 作用域
}

// CredentialDeleteReq 删除凭据请求
type CredentialDeleteReq struct {
	Id uint64 `json:"id" binding:"required"` // 凭据数据库ID
}

// CredentialBatchDeleteReq 批量删除凭据请求
type CredentialBatchDeleteReq struct {
	Ids []uint64 `json:"ids" binding:"required"` // 凭据数据库ID列表
}

// CredentialDetailReq 凭据详情请求
type CredentialDetailReq struct {
	Id uint64 `json:"id" form:"id" binding:"required"` // 凭据数据库ID
}

// CredentialResponse 凭据响应
type CredentialResponse struct {
	Id           uint64    `json:"id"`
	CredentialId string    `json:"credentialId"`
	Description  string    `json:"description"`
	Type         string    `json:"type"`
	Username     string    `json:"username"`
	Scope        string    `json:"scope"`
	UsageCount   int       `json:"usageCount"`
	CreatedTime  time.Time `json:"createdTime"`
	UpdatedTime  time.Time `json:"updatedTime"`
	Creator      string    `json:"creator"`
	Modifier     string    `json:"modifier"`
}

// CredentialDetailResponse 凭据详情响应（包含敏感信息脱敏）
type CredentialDetailResponse struct {
	CredentialResponse
	PasswordMasked    string `json:"passwordMasked,omitempty"`    // 脱敏密码
	PrivateKeyMasked  string `json:"privateKeyMasked,omitempty"`  // 脱敏私钥
	PassphraseMasked  string `json:"passphraseMasked,omitempty"`  // 脱敏密码短语
	SecretTextMasked  string `json:"secretTextMasked,omitempty"`  // 脱敏密钥文本
	CertificateMasked string `json:"certificateMasked,omitempty"` // 脱敏证书
}

// GetCredentialList 获取凭据列表
func GetCredentialList(c *lib.GinContext) error {
	var req CredentialListReq
	if err := c.Bind(&req); err != nil {
		c.Logger().Error("参数绑定失败：" + err.Error())
		return response.JsonFail(c, "参数错误")
	}

	// 设置默认分页参数
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.Size <= 0 {
		req.Size = 10
	}

	// 构建查询
	db := model.DB().Model(&model.JenkinsCredential{}).Where("deleted = 0")

	// 关键词搜索
	if req.Keyword != "" {
		keyword := "%" + req.Keyword + "%"
		db = db.Where("credential_id LIKE ? OR description LIKE ?", keyword, keyword)
	}

	// 类型筛选
	if req.Type != "" {
		db = db.Where("type = ?", req.Type)
	}

	// 获取总数
	var total int64
	if err := db.Count(&total).Error; err != nil {
		c.Logger().Error("查询凭据总数失败：" + err.Error())
		return response.JsonFail(c, "查询失败")
	}

	// 分页查询
	offset := (req.Page - 1) * req.Size
	var credentials []model.JenkinsCredential
	if err := db.Offset(offset).Limit(req.Size).Order("create_time DESC").Find(&credentials).Error; err != nil {
		c.Logger().Error("查询凭据列表失败：" + err.Error())
		return response.JsonFail(c, "查询失败")
	}

	// 转换响应格式
	var records []CredentialResponse
	for _, cred := range credentials {
		records = append(records, CredentialResponse{
			Id:           cred.Id,
			CredentialId: cred.CredentialId,
			Description:  cred.Description,
			Type:         cred.Type,
			Username:     cred.Username,
			Scope:        cred.Scope,
			UsageCount:   cred.UsageCount,
			CreatedTime:  *cred.CreateTime,
			UpdatedTime:  *cred.UpdateTime,
			Creator:      cred.Creator,
			Modifier:     cred.Modifier,
		})
	}

	result := common.PageRes{
		Total:   total,
		Records: records,
	}

	return response.JsonOk(c, result, "查询成功")
}

// CreateCredential 创建凭据
func CreateCredential(c *lib.GinContext) error {
	var req CredentialCreateReq
	if err := c.Bind(&req); err != nil {
		c.Logger().Error("参数绑定失败：" + err.Error())
		return response.JsonFail(c, "参数错误")
	}

	// 验证凭据类型
	if !isValidCredentialType(req.Type) {
		return response.JsonFail(c, "不支持的凭据类型")
	}

	// 验证凭据ID唯一性
	var existingCred model.JenkinsCredential
	if err := model.DB().Where("credential_id = ? AND deleted = 0", req.CredentialId).First(&existingCred).Error; err == nil {
		return response.JsonFail(c, "凭据ID已存在")
	}

	// 创建凭据对象
	credential := &model.JenkinsCredential{
		CredentialId: req.CredentialId,
		Description:  req.Description,
		Type:         req.Type,
		Username:     req.Username,
		Scope:        getValidScope(req.Scope),
	}

	// 根据类型设置相应的敏感信息
	if err := setCredentialSensitiveData(credential, req); err != nil {
		c.Logger().Error("设置凭据敏感信息失败：" + err.Error())
		return response.JsonFail(c, "创建凭据失败")
	}

	// 保存到数据库
	if err := model.DBWithGinContext(c).Create(credential).Error; err != nil {
		c.Logger().Error("保存凭据到数据库失败：" + err.Error())
		return response.JsonFail(c, "创建凭据失败")
	}

	// 同步到Jenkins
	go func() {
		if err := syncCredentialToJenkins(credential, "create"); err != nil {
			c.Logger().Error("同步凭据到Jenkins失败：" + err.Error())
		}
	}()

	return response.JsonOk(c, credential.Id, "创建凭据成功")
}

// UpdateCredential 更新凭据
func UpdateCredential(c *lib.GinContext) error {
	var req CredentialUpdateReq
	if err := c.Bind(&req); err != nil {
		c.Logger().Error("参数绑定失败：" + err.Error())
		return response.JsonFail(c, "参数错误")
	}

	// 验证凭据类型
	if !isValidCredentialType(req.Type) {
		return response.JsonFail(c, "不支持的凭据类型")
	}

	// 查找现有凭据
	var credential model.JenkinsCredential
	if err := model.DB().Where("id = ? AND deleted = 0", req.Id).First(&credential).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return response.JsonFail(c, "凭据不存在")
		}
		c.Logger().Error("查询凭据失败：" + err.Error())
		return response.JsonFail(c, "查询凭据失败")
	}

	// 检查凭据ID是否被其他记录使用
	if req.CredentialId != credential.CredentialId {
		var existingCred model.JenkinsCredential
		if err := model.DB().Where("credential_id = ? AND id != ? AND deleted = 0", req.CredentialId, req.Id).First(&existingCred).Error; err == nil {
			return response.JsonFail(c, "凭据ID已存在")
		}
	}

	// 保存旧的凭据ID用于Jenkins同步
	oldCredentialId := credential.CredentialId

	// 更新基本信息
	credential.CredentialId = req.CredentialId
	credential.Description = req.Description
	credential.Type = req.Type
	credential.Username = req.Username
	credential.Scope = getValidScope(req.Scope)

	// 根据类型设置相应的敏感信息
	if err := setCredentialSensitiveData(&credential, CredentialCreateReq{
		Password:    req.Password,
		PrivateKey:  req.PrivateKey,
		Passphrase:  req.Passphrase,
		SecretText:  req.SecretText,
		Certificate: req.Certificate,
	}); err != nil {
		c.Logger().Error("设置凭据敏感信息失败：" + err.Error())
		return response.JsonFail(c, "更新凭据失败")
	}

	// 保存到数据库
	if err := model.DBWithGinContext(c).Save(&credential).Error; err != nil {
		c.Logger().Error("保存凭据到数据库失败：" + err.Error())
		return response.JsonFail(c, "更新凭据失败")
	}

	// 同步到Jenkins
	go func() {
		// 如果凭据ID发生变化，需要先删除旧的，再创建新的
		if oldCredentialId != credential.CredentialId {
			if err := deleteCredentialFromJenkins(oldCredentialId); err != nil {
				c.Logger().Error("从Jenkins删除旧凭据失败：" + err.Error())
			}
			if err := syncCredentialToJenkins(&credential, "create"); err != nil {
				c.Logger().Error("同步新凭据到Jenkins失败：" + err.Error())
			}
		} else {
			if err := syncCredentialToJenkins(&credential, "update"); err != nil {
				c.Logger().Error("同步凭据到Jenkins失败：" + err.Error())
			}
		}
	}()

	return response.JsonOk(c, credential.Id, "更新凭据成功")
}

// DeleteCredential 删除凭据
func DeleteCredential(c *lib.GinContext) error {
	var req CredentialDeleteReq
	if err := c.Bind(&req); err != nil {
		c.Logger().Error("参数绑定失败：" + err.Error())
		return response.JsonFail(c, "参数错误")
	}

	// 查找凭据
	var credential model.JenkinsCredential
	if err := model.DB().Where("id = ? AND deleted = 0", req.Id).First(&credential).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return response.JsonFail(c, "凭据不存在")
		}
		c.Logger().Error("查询凭据失败：" + err.Error())
		return response.JsonFail(c, "查询凭据失败")
	}

	// 软删除
	now := time.Now()
	if err := model.DB().Model(&credential).Updates(map[string]interface{}{
		"deleted":     1,
		"delete_time": &now,
	}).Error; err != nil {
		c.Logger().Error("删除凭据失败：" + err.Error())
		return response.JsonFail(c, "删除凭据失败")
	}

	// 从Jenkins删除
	go func() {
		if err := deleteCredentialFromJenkins(credential.CredentialId); err != nil {
			c.Logger().Error("从Jenkins删除凭据失败：" + err.Error())
		}
	}()

	return response.JsonOk(c, nil, "删除凭据成功")
}

// BatchDeleteCredentials 批量删除凭据
func BatchDeleteCredentials(c *lib.GinContext) error {
	var req CredentialBatchDeleteReq
	if err := c.Bind(&req); err != nil {
		c.Logger().Error("参数绑定失败：" + err.Error())
		return response.JsonFail(c, "参数错误")
	}

	if len(req.Ids) == 0 {
		return response.JsonFail(c, "请选择要删除的凭据")
	}

	// 查找所有要删除的凭据
	var credentials []model.JenkinsCredential
	if err := model.DB().Where("id IN ? AND deleted = 0", req.Ids).Find(&credentials).Error; err != nil {
		c.Logger().Error("查询凭据失败：" + err.Error())
		return response.JsonFail(c, "查询凭据失败")
	}

	if len(credentials) == 0 {
		return response.JsonFail(c, "没有找到要删除的凭据")
	}

	// 批量软删除
	now := time.Now()
	if err := model.DB().Model(&model.JenkinsCredential{}).Where("id IN ?", req.Ids).Updates(map[string]interface{}{
		"deleted":     1,
		"delete_time": &now,
	}).Error; err != nil {
		c.Logger().Error("批量删除凭据失败：" + err.Error())
		return response.JsonFail(c, "批量删除凭据失败")
	}

	// 从Jenkins批量删除
	go func() {
		for _, credential := range credentials {
			if err := deleteCredentialFromJenkins(credential.CredentialId); err != nil {
				c.Logger().Error(fmt.Sprintf("从Jenkins删除凭据%s失败：%s", credential.CredentialId, err.Error()))
			}
		}
	}()

	return response.JsonOk(c, nil, fmt.Sprintf("成功删除%d个凭据", len(credentials)))
}

// GetCredentialDetail 获取凭据详情
func GetCredentialDetail(c *lib.GinContext) error {
	var req CredentialDetailReq
	if err := c.Bind(&req); err != nil {
		c.Logger().Error("参数绑定失败：" + err.Error())
		return response.JsonFail(c, "参数错误")
	}

	// 查找凭据
	var credential model.JenkinsCredential
	if err := model.DB().Where("id = ? AND deleted = 0", req.Id).First(&credential).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return response.JsonFail(c, "凭据不存在")
		}
		c.Logger().Error("查询凭据失败：" + err.Error())
		return response.JsonFail(c, "查询凭据失败")
	}

	// 构建响应（敏感信息脱敏）
	detail := CredentialDetailResponse{
		CredentialResponse: CredentialResponse{
			Id:           credential.Id,
			CredentialId: credential.CredentialId,
			Description:  credential.Description,
			Type:         credential.Type,
			Username:     credential.Username,
			Scope:        credential.Scope,
			UsageCount:   credential.UsageCount,
			CreatedTime:  *credential.CreateTime,
			UpdatedTime:  *credential.UpdateTime,
			Creator:      credential.Creator,
			Modifier:     credential.Modifier,
		},
	}

	// 根据类型添加脱敏的敏感信息
	switch credential.Type {
	case model.CredentialTypeUsernamePassword:
		if password, err := credential.GetPassword(); err == nil && password != "" {
			detail.PasswordMasked = maskSensitiveData(password)
		}
	case model.CredentialTypeSSHKey:
		if privateKey, err := credential.GetPrivateKey(); err == nil && privateKey != "" {
			detail.PrivateKeyMasked = maskSensitiveData(privateKey)
		}
		if passphrase, err := credential.GetPassphrase(); err == nil && passphrase != "" {
			detail.PassphraseMasked = maskSensitiveData(passphrase)
		}
	case model.CredentialTypeSecretText:
		if secretText, err := credential.GetSecretText(); err == nil && secretText != "" {
			detail.SecretTextMasked = maskSensitiveData(secretText)
		}
	case model.CredentialTypeCertificate:
		if certificate, err := credential.GetCertificate(); err == nil && certificate != "" {
			detail.CertificateMasked = maskSensitiveData(certificate)
		}
	}

	return response.JsonOk(c, detail, "查询成功")
}

// 辅助函数

// isValidCredentialType 验证凭据类型是否有效
func isValidCredentialType(credType string) bool {
	validTypes := []string{
		model.CredentialTypeUsernamePassword,
		model.CredentialTypeSSHKey,
		model.CredentialTypeSecretText,
		model.CredentialTypeCertificate,
	}
	for _, validType := range validTypes {
		if credType == validType {
			return true
		}
	}
	return false
}

// getValidScope 获取有效的作用域
func getValidScope(scope string) string {
	if scope == model.CredentialScopeSystem {
		return model.CredentialScopeSystem
	}
	return model.CredentialScopeGlobal
}

// setCredentialSensitiveData 根据凭据类型设置敏感数据
func setCredentialSensitiveData(credential *model.JenkinsCredential, req CredentialCreateReq) error {
	switch credential.Type {
	case model.CredentialTypeUsernamePassword:
		if req.Password != "" {
			if err := credential.SetPassword(req.Password); err != nil {
				return err
			}
		}
	case model.CredentialTypeSSHKey:
		if req.PrivateKey != "" {
			if err := credential.SetPrivateKey(req.PrivateKey); err != nil {
				return err
			}
		}
		if req.Passphrase != "" {
			if err := credential.SetPassphrase(req.Passphrase); err != nil {
				return err
			}
		}
	case model.CredentialTypeSecretText:
		if req.SecretText != "" {
			if err := credential.SetSecretText(req.SecretText); err != nil {
				return err
			}
		}
	case model.CredentialTypeCertificate:
		if req.Certificate != "" {
			if err := credential.SetCertificate(req.Certificate); err != nil {
				return err
			}
		}
	}
	return nil
}

// maskSensitiveData 脱敏敏感数据
func maskSensitiveData(data string) string {
	if len(data) <= 8 {
		return "****" + data[len(data)-2:]
	}
	return "****" + data[len(data)-4:]
}

// syncCredentialToJenkins 同步凭据到Jenkins
func syncCredentialToJenkins(credential *model.JenkinsCredential, action string) error {
	// 建立Jenkins连接
	if model.JenkinsConnection == nil {
		return fmt.Errorf("Jenkins连接未初始化")
	}
	jenkinsConn := model.JenkinsConnection

	// 根据凭据类型创建不同的Jenkins凭据
	switch credential.Type {
	case model.CredentialTypeUsernamePassword:
		return syncUsernamePasswordCredential(jenkinsConn, credential, action)
	case model.CredentialTypeSSHKey:
		return syncSSHKeyCredential(jenkinsConn, credential, action)
	case model.CredentialTypeSecretText:
		return syncSecretTextCredential(jenkinsConn, credential, action)
	case model.CredentialTypeCertificate:
		return syncCertificateCredential(jenkinsConn, credential, action)
	default:
		return fmt.Errorf("不支持的凭据类型: %s", credential.Type)
	}
}

// syncUsernamePasswordCredential 同步用户名密码凭据
func syncUsernamePasswordCredential(jenkins *gojenkins.Jenkins, credential *model.JenkinsCredential, action string) error {
	password, err := credential.GetPassword()
	if err != nil {
		return fmt.Errorf("获取密码失败: %v", err)
	}

	// 构建Jenkins凭据XML
	credXML := fmt.Sprintf(`
<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
  <scope>%s</scope>
  <id>%s</id>
  <description>%s</description>
  <username>%s</username>
  <password>%s</password>
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
`, credential.Scope, credential.CredentialId, credential.Description, credential.Username, password)

	return createOrUpdateJenkinsCredential(jenkins, credential.CredentialId, credXML, action)
}

// syncSSHKeyCredential 同步SSH密钥凭据
func syncSSHKeyCredential(jenkins *gojenkins.Jenkins, credential *model.JenkinsCredential, action string) error {
	privateKey, err := credential.GetPrivateKey()
	if err != nil {
		return fmt.Errorf("获取私钥失败: %v", err)
	}

	passphrase, _ := credential.GetPassphrase()

	// 构建Jenkins凭据XML
	credXML := fmt.Sprintf(`
<com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey>
  <scope>%s</scope>
  <id>%s</id>
  <description>%s</description>
  <username>%s</username>
  <passphrase>%s</passphrase>
  <privateKeySource class="com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey$DirectEntryPrivateKeySource">
    <privateKey>%s</privateKey>
  </privateKeySource>
</com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey>
`, credential.Scope, credential.CredentialId, credential.Description, credential.Username, passphrase, privateKey)

	return createOrUpdateJenkinsCredential(jenkins, credential.CredentialId, credXML, action)
}

// syncSecretTextCredential 同步密钥文本凭据
func syncSecretTextCredential(jenkins *gojenkins.Jenkins, credential *model.JenkinsCredential, action string) error {
	secretText, err := credential.GetSecretText()
	if err != nil {
		return fmt.Errorf("获取密钥文本失败: %v", err)
	}

	// 构建Jenkins凭据XML
	credXML := fmt.Sprintf(`
<org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl>
  <scope>%s</scope>
  <id>%s</id>
  <description>%s</description>
  <secret>%s</secret>
</org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl>
`, credential.Scope, credential.CredentialId, credential.Description, secretText)

	return createOrUpdateJenkinsCredential(jenkins, credential.CredentialId, credXML, action)
}

// syncCertificateCredential 同步证书凭据
func syncCertificateCredential(jenkins *gojenkins.Jenkins, credential *model.JenkinsCredential, action string) error {
	certificate, err := credential.GetCertificate()
	if err != nil {
		return fmt.Errorf("获取证书失败: %v", err)
	}

	// 构建Jenkins凭据XML
	credXML := fmt.Sprintf(`
<com.cloudbees.plugins.credentials.impl.CertificateCredentialsImpl>
  <scope>%s</scope>
  <id>%s</id>
  <description>%s</description>
  <keyStoreSource class="com.cloudbees.plugins.credentials.impl.CertificateCredentialsImpl$DirectEntryKeyStoreSource">
    <keyStore>%s</keyStore>
  </keyStoreSource>
</com.cloudbees.plugins.credentials.impl.CertificateCredentialsImpl>
`, credential.Scope, credential.CredentialId, credential.Description, certificate)

	return createOrUpdateJenkinsCredential(jenkins, credential.CredentialId, credXML, action)
}

// createOrUpdateJenkinsCredential 创建或更新Jenkins凭据
func createOrUpdateJenkinsCredential(jenkins *gojenkins.Jenkins, credentialId, credXML, action string) error {
	// 创建带cookie jar的HTTP客户端
	jar, err := cookiejar.New(nil)
	if err != nil {
		return fmt.Errorf("创建cookie jar失败: %v", err)
	}
	client := &http.Client{Jar: jar}

	// 获取CSRF令牌
	crumbURL := model.C.General.JenkinsUrl + "/crumbIssuer/api/json"
	crumb, err := getJenkinsCrumbWithClient(crumbURL, client)
	if err != nil {
		return fmt.Errorf("获取CSRF令牌失败: %v", err)
	}

	// 构建API URL
	var apiURL string
	var method string
	if action == "create" {
		apiURL = model.C.General.JenkinsUrl + "/credentials/store/system/domain/_/createCredentials"
		method = "POST"
	} else {
		apiURL = model.C.General.JenkinsUrl + fmt.Sprintf("/credentials/store/system/domain/_/credential/%s/config.xml", credentialId)
		method = "POST"
	}

	// 创建HTTP请求
	req, err := http.NewRequest(method, apiURL, strings.NewReader(credXML))
	if err != nil {
		return fmt.Errorf("创建HTTP请求失败: %v", err)
	}

	// 设置认证头
	auth := base64.StdEncoding.EncodeToString([]byte(model.C.General.JenkinsUsername + ":" + model.C.General.JenkinsPassword))
	req.Header.Set("Authorization", "Basic "+auth)
	req.Header.Set("Content-Type", "application/xml;charset=UTF-8")

	// 设置CSRF令牌
	if crumb.CrumbRequestField != "" && crumb.Crumb != "" {
		req.Header.Set(crumb.CrumbRequestField, crumb.Crumb)
	}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("发送HTTP请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 检查响应状态
	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		body, _ := io.ReadAll(resp.Body)
		return fmt.Errorf("Jenkins API调用失败，状态码: %d, 响应: %s", resp.StatusCode, string(body))
	}

	return nil
}

// deleteCredentialFromJenkins 从Jenkins删除凭据
func deleteCredentialFromJenkins(credentialId string) error {
	// 创建带cookie jar的HTTP客户端
	jar, err := cookiejar.New(nil)
	if err != nil {
		return fmt.Errorf("创建cookie jar失败: %v", err)
	}
	client := &http.Client{Jar: jar}

	// 获取CSRF令牌
	crumbURL := model.C.General.JenkinsUrl + "/crumbIssuer/api/json"
	crumb, err := getJenkinsCrumbWithClient(crumbURL, client)
	if err != nil {
		return fmt.Errorf("获取CSRF令牌失败: %v", err)
	}

	// 构建删除API URL
	apiURL := model.C.General.JenkinsUrl + fmt.Sprintf("/credentials/store/system/domain/_/credential/%s/doDelete", credentialId)

	// 创建HTTP请求
	req, err := http.NewRequest("POST", apiURL, nil)
	if err != nil {
		return fmt.Errorf("创建HTTP请求失败: %v", err)
	}

	// 设置认证头
	auth := base64.StdEncoding.EncodeToString([]byte(model.C.General.JenkinsUsername + ":" + model.C.General.JenkinsPassword))
	req.Header.Set("Authorization", "Basic "+auth)

	// 设置CSRF令牌
	if crumb.CrumbRequestField != "" && crumb.Crumb != "" {
		req.Header.Set(crumb.CrumbRequestField, crumb.Crumb)
	}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("发送HTTP请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 检查响应状态
	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		body, _ := io.ReadAll(resp.Body)
		return fmt.Errorf("Jenkins API调用失败，状态码: %d, 响应: %s", resp.StatusCode, string(body))
	}

	return nil
}

// GetCredentialOptions 获取凭据选项
func GetCredentialOptions(c *lib.GinContext) error {
	var credentials []model.JenkinsCredential
	err := model.DB().Select("credential_id").Where("deleted = 0").Find(&credentials).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		c.Logger().Error(err.Error())
		return response.JsonFail(c, "查询失败")
	}

	var options []common.OptionRes
	for _, credential := range credentials {
		options = append(options, common.OptionRes{
			Label: credential.CredentialId,
			Value: credential.CredentialId,
		})
	}

	return response.JsonOk(c, options, "查询成功")
}

// JenkinsCrumb Jenkins CSRF令牌结构
type JenkinsCrumb struct {
	Crumb             string `json:"crumb"`
	CrumbRequestField string `json:"crumbRequestField"`
}

// getJenkinsCrumbWithClient 使用指定的HTTP客户端获取Jenkins CSRF令牌
func getJenkinsCrumbWithClient(crumbURL string, client *http.Client) (*JenkinsCrumb, error) {
	// 创建HTTP请求
	req, err := http.NewRequest("GET", crumbURL, nil)
	if err != nil {
		return nil, fmt.Errorf("创建HTTP请求失败: %v", err)
	}

	// 设置认证头
	auth := base64.StdEncoding.EncodeToString([]byte(model.C.General.JenkinsUsername + ":" + model.C.General.JenkinsPassword))
	req.Header.Set("Authorization", "Basic "+auth)
	req.Header.Set("Accept", "application/json")

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("发送HTTP请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 检查响应状态
	if resp.StatusCode != 200 {
		// 如果Jenkins没有启用CSRF保护，返回空的crumb
		if resp.StatusCode == 404 {
			return &JenkinsCrumb{}, nil
		}
		body, _ := io.ReadAll(resp.Body)
		return nil, fmt.Errorf("获取CSRF令牌失败，状态码: %d, 响应: %s", resp.StatusCode, string(body))
	}

	// 解析响应
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应失败: %v", err)
	}

	var crumb JenkinsCrumb
	if err := json.Unmarshal(body, &crumb); err != nil {
		return nil, fmt.Errorf("解析CSRF令牌失败: %v", err)
	}

	return &crumb, nil
}
